home *** CD-ROM | disk | FTP | other *** search
/ Team Palmtops 7 / Palmtops_numero07.iso / WinCE / SDKWindowsCE / HandHeldPCPro30 / sdk.exe / Jupiter SDK / data1.cab / MFC_Samples / mtgdi / mtgdivw.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  1999-02-19  |  8.3 KB  |  352 lines

  1. // mtgdivw.cpp : implementation of the CThreadView class
  2. //
  3. // This is a part of the Microsoft Foundation Classes C++ library.
  4. // Copyright (C) 1999 Microsoft Corporation
  5. // All rights reserved.
  6. //
  7. // This source code is only intended as a supplement to the
  8. // Microsoft Foundation Classes Reference and related
  9. // electronic documentation provided with the library.
  10. // See these sources for detailed information regarding the
  11. // Microsoft Foundation Classes product.
  12.  
  13. #include "stdafx.h"
  14. #include "mtgdi.h"
  15.  
  16. #include "mtgdidoc.h"
  17. #include "mtgdivw.h"
  18.  
  19. #ifdef _DEBUG
  20. #undef THIS_FILE
  21. static char BASED_CODE THIS_FILE[] = __FILE__;
  22. #endif
  23.  
  24. /////////////////////////////////////////////////////////////////////////////
  25. // CThreadView
  26.  
  27. IMPLEMENT_DYNCREATE(CThreadView, CView)
  28.  
  29. BEGIN_MESSAGE_MAP(CThreadView, CView)
  30.     //{{AFX_MSG_MAP(CThreadView)
  31.     ON_COMMAND(ID_BALL_NEWBALL, OnNewBall)
  32.     ON_COMMAND(ID_FILE_KILLTHREADS, OnKillThreads)
  33.     ON_WM_DESTROY()
  34.     ON_COMMAND(ID_LINE_NEWLINE, OnNewLine)
  35.     ON_COMMAND(ID_RECT_NEWRECTANGLE, OnNewRectangle)
  36.     ON_COMMAND(ID_BALL_10NEWBALLS, On10NewBalls)
  37.     ON_COMMAND(ID_LINE_10NEWLINES, On10NewLines)
  38.     ON_COMMAND(ID_RECT_10NEWRECTANGLES, On10NewRectangles)
  39.     ON_WM_CREATE()
  40.     ON_WM_SIZE()
  41.     ON_COMMAND(ID_BALL_25NEWBALLS, On25NewBalls)
  42.     ON_COMMAND(ID_LINE_25NEWLINES, On25NewLines)
  43.     ON_COMMAND(ID_RECT_25NEWRECTANGLES, On25NewRectangles)
  44.     ON_COMMAND(ID_FILE_KILLTHREADSSLOW, OnThreadKillThreadsSlow)
  45.     //}}AFX_MSG_MAP
  46. END_MESSAGE_MAP()
  47.  
  48. /////////////////////////////////////////////////////////////////////////////
  49. // CThreadView construction/destruction
  50.  
  51. CThreadView::CThreadView()
  52. {
  53.     m_pDC = NULL;
  54. }
  55.  
  56. CThreadView::~CThreadView()
  57. {
  58. }
  59.  
  60. void CThreadView::UpdateTitle(int nThreads)
  61. {
  62.     if (nThreads == -1)
  63.         nThreads = m_threadList.GetCount();
  64.  
  65.     CString strCaption;
  66.     if (nThreads != 0)
  67.     {
  68.         CString strFormat; strFormat.LoadString(IDS_CAPTION_FORMAT);
  69.         strCaption.Format(strFormat, nThreads);
  70.     }
  71.     else
  72.          strCaption.LoadString(IDS_CAPTION_NOTHREADS);
  73.  
  74.     GetParentFrame()->SetWindowText(strCaption);
  75. }
  76.  
  77. BOOL CThreadView::StartThread(int ThreadID)
  78. {
  79.     CGDIThread* pThread;
  80.     CPoint Pos(rand()%100,rand()%100);
  81.     CPoint Vel1((rand()%10)+2,(rand()%10)+2); 
  82.     CPoint Vel2((rand()%5)+2,(rand()%5)+2);
  83.     CSize Size(((rand()%60)+20),((rand()%60)+20));
  84.     COLORREF Color;
  85.     
  86.     // Calculate random color
  87.     // For shades of gray, r == g == b
  88.     int r = (rand()%4);
  89. #if (_WIN32_WCE < 101) && !defined(_WIN32_WCE_EMULATION)
  90.     //Note: For os 100, color handled differently on an HPC    
  91.     r = (r!=0) ? (r!=1) ? (r==3) ? 255 : 2 : 1 : 0;
  92. #else
  93.     r = (r!=0) ? (r!=1) ? (r==3) ? 255 : 192 : 128 : 0;
  94. #endif
  95.     Color = RGB(r,r,r);
  96.  
  97.     if (rand()%1) Vel1.x*=-1;
  98.     if (rand()%1) Vel1.y*=-1;
  99.     if (rand()%1) Vel2.x*=-1;
  100.     if (rand()%1) Vel2.y*=-1;
  101.  
  102.     switch(ThreadID)
  103.     {
  104.     case 1:
  105.         pThread = new CBallThread(this, 
  106.             m_pDC->GetSafeHdc(), Pos, Vel1, Size, Color);
  107.         break;
  108.     case 2:
  109.         pThread = new CRectThread(this, 
  110.             m_pDC->GetSafeHdc(), Pos, Vel1, Size, Color);
  111.         break;
  112.     case 3:
  113.         pThread = new CLineThread(this, 
  114.             m_pDC->GetSafeHdc(), Pos, Vel1, Vel2, Size, Color);
  115.         break;
  116.     }
  117.  
  118.     if (pThread == NULL)
  119.         return FALSE;
  120.  
  121.     ASSERT_VALID(pThread);
  122.     pThread->m_pThreadParams = NULL;
  123.  
  124.     // Create Thread in a suspended state so we can set the Priority 
  125.     // before it starts getting away from us
  126.     if (!pThread->CreateThread(CREATE_SUSPENDED))
  127.     {
  128.         delete pThread;
  129.         AfxMessageBox(CString((LPCTSTR)IDS_LIMIT));
  130.         return FALSE;  
  131.     }
  132.  
  133.     // since everything is successful, add the thread to our list
  134.     m_threadList.AddTail(pThread);
  135.  
  136.     // If you want to make the sample more sprightly, set the thread priority here 
  137.     // a little higher. It has been set at idle priority to keep from bogging down 
  138.     // other apps that may also be running.
  139.     VERIFY(pThread->SetThreadPriority(THREAD_PRIORITY_IDLE));
  140.  
  141.     // Now the thread can run wild
  142.     pThread->ResumeThread();
  143.  
  144.     return TRUE;
  145. }
  146.  
  147. void CThreadView::OnDraw(CDC*)
  148. {
  149. }
  150.  
  151. /////////////////////////////////////////////////////////////////////////////
  152. // CThreadView diagnostics
  153.  
  154. #ifdef _DEBUG
  155. void CThreadView::AssertValid() const
  156. {
  157.     CView::AssertValid();
  158. }
  159.  
  160. void CThreadView::Dump(CDumpContext& dc) const
  161. {
  162.     CView::Dump(dc);
  163. }
  164.  
  165. CThreadDoc* CThreadView::GetDocument() // non-debug version is inline
  166. {
  167.     return STATIC_DOWNCAST(CThreadDoc, m_pDocument);
  168. }
  169. #endif //_DEBUG
  170.  
  171. /////////////////////////////////////////////////////////////////////////////
  172. // CThreadView message handlers
  173.  
  174. void CThreadView::OnNewBall() 
  175. {
  176.     StartThread(1);
  177.     UpdateTitle();
  178. }
  179.  
  180. void CThreadView::On10NewBalls() 
  181. {
  182.     for (int i = 0; i < 10; i++) 
  183.     {
  184.         if(!StartThread(1))
  185.             break;
  186.         UpdateTitle();
  187.     }
  188. }
  189.  
  190. void CThreadView::On25NewBalls() 
  191. {
  192.     for (int i = 0; i < 25; i++) 
  193.     {
  194.         if(!StartThread(1))
  195.             break;
  196.         UpdateTitle();
  197.     }
  198. }
  199.  
  200. void CThreadView::OnNewRectangle() 
  201. {
  202.     StartThread(2);
  203.     UpdateTitle();
  204. }
  205.  
  206. void CThreadView::On10NewRectangles() 
  207. {
  208.     for (int i = 0; i < 10; i++) 
  209.     {
  210.         if(!StartThread(2))
  211.             break;
  212.         UpdateTitle();
  213.     }
  214. }
  215.  
  216. void CThreadView::On25NewRectangles() 
  217. {
  218.     for (int i = 0; i < 25; i++) 
  219.     {
  220.         if(!StartThread(2))
  221.             break;
  222.         UpdateTitle();
  223.     }
  224. }
  225.  
  226. void CThreadView::OnNewLine() 
  227. {
  228.     StartThread(3);
  229.     UpdateTitle();
  230. }
  231.  
  232. void CThreadView::On10NewLines() 
  233. {
  234.     for (int i = 0 ;i < 10; i++) 
  235.     {
  236.         if(!StartThread(3))
  237.             break;
  238.         UpdateTitle();
  239.     }
  240. }    
  241.     
  242. void CThreadView::On25NewLines() 
  243. {
  244.     for (int i = 0; i < 25; i++) 
  245.     {
  246.         if(!StartThread(3))
  247.             break;
  248.         UpdateTitle();
  249.     }
  250. }
  251.  
  252. // A preferred method for killing many threads.  Tell them to go away all
  253. // at once, then wait for them all to be scheduled and to terminate
  254. // themselves.  This is much, much faster than the more straight forward
  255. // way of asking just one to terminate, then waiting for it to do so.
  256. // It is also a little bit more complex.
  257.  
  258. void CThreadView::OnKillThreads() 
  259. {
  260.     // tell all threads to shutdown
  261.     for (POSITION pos = m_threadList.GetHeadPosition(); pos != NULL; )
  262.     {
  263.         CGDIThread* pThread = m_threadList.GetNext(pos);
  264.     #ifdef _WIN32_WCE_EMULATION
  265.         VERIFY(SetEvent(pThread->m_hEventKill));
  266.     #else
  267.         VERIFY(EventModify(pThread->m_hEventKill, EVENT_SET));
  268.     #endif
  269.     }
  270.  
  271.     // wait for all threads to finish shutdown
  272.     for (int nThreadsLeft = m_threadList.GetCount(); nThreadsLeft != 0; )
  273.     {
  274.         WaitForSingleObject(CGDIThread::m_hAnotherDead, INFINITE);
  275.         Sleep(nThreadsLeft*2);// 200ms for every 100 threads
  276.         nThreadsLeft = 0;
  277.         for (pos = m_threadList.GetHeadPosition(); pos != NULL; )
  278.         {
  279.             CGDIThread* pThread = m_threadList.GetNext(pos);
  280.             if (WaitForSingleObject(pThread->m_hEventDead, 0) == WAIT_TIMEOUT)
  281.                 ++nThreadsLeft;
  282.         }
  283.         UpdateTitle(nThreadsLeft);
  284.     }
  285.  
  286.     // delete all thread objects
  287.     while (!m_threadList.IsEmpty())
  288.     {
  289.         CGDIThread* pThread = m_threadList.RemoveHead();
  290.         VERIFY(WaitForSingleObject(pThread->m_hThread, INFINITE) == WAIT_OBJECT_0);
  291.         delete pThread;
  292.     }
  293.     UpdateTitle();
  294.  
  295.     // invalidate the window since all threads are now gone
  296.     Invalidate();
  297. }
  298.  
  299. // KillThreadsSlow is much easier to understand since the process of 
  300. // killing a thread is encapsulated in KillThread.  If you get more 
  301. // than 50 threads running, however, you'll notice quite a difference
  302. // between this method and the one above.
  303.  
  304. void CThreadView::OnThreadKillThreadsSlow() 
  305. {
  306.     // Iterate through the threads killing each
  307.     // KillThread doesn't return until the Thread is dead
  308.     while (!m_threadList.IsEmpty())
  309.     {
  310.         m_threadList.RemoveHead()->KillThread();
  311.         UpdateTitle();
  312.     }
  313.  
  314.     // Invalidate the window so it blanks the window
  315.     Invalidate();
  316. }
  317.  
  318. void CThreadView::OnDestroy() 
  319. {
  320.     while (!m_threadList.IsEmpty())
  321.         m_threadList.RemoveHead()->KillThread();
  322.  
  323.     delete m_pDC;
  324.     m_pDC = NULL;
  325.  
  326.     CView::OnDestroy();
  327. }
  328.  
  329. int CThreadView::OnCreate(LPCREATESTRUCT lpCreateStruct) 
  330. {
  331.     if (CView::OnCreate(lpCreateStruct) == -1)
  332.         return -1;
  333.     
  334.     // m_pDC must be initialized here instead of the constructor
  335.     // because the HWND isn't created until Create is called.
  336.     m_pDC = new CClientDC(this);
  337.     UpdateTitle();
  338.  
  339.     return 0;
  340. }
  341.  
  342. void CThreadView::OnSize(UINT nType, int cx, int cy) 
  343. {
  344.     CView::OnSize(nType, cx, cy);
  345.     
  346.     // Instead of getting the client rect every time we draw, we only
  347.     // update it when it changes.
  348.     for (POSITION pos = m_threadList.GetHeadPosition(); pos != NULL; )
  349.         m_threadList.GetNext(pos)->UpdateBorder();
  350. }
  351.  
  352.